package boot.spring.service.impl;


import boot.spring.mapper.DynamicSqlMapper;
import boot.spring.service.DorisTableService;
import com.baomidou.dynamic.datasource.annotation.DS;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

@Service
@Slf4j
@DS("doris")
public class DorisTableServiceImpl implements DorisTableService {

    @Autowired
    private DynamicSqlMapper sqlMapper;

    /**
     * 缓存已有表名：key = schema, value = Set<table>
     */
    private final Map<String, Set<String>> tableCache = new ConcurrentHashMap<>();

    @Override
    public boolean createTable(String schema, String newTable, String templateTable, boolean ifNotExists) {
        long startTime = System.currentTimeMillis();
        boolean success = false;

        try {
            // 先检查缓存
            if (ifNotExists && tableExists(schema, newTable)) {
                log.info("Table [{}] exists in cache, skip creation", newTable);
                return true;
            }

            String sql = String.format("CREATE TABLE %s %s.%s LIKE %s.%s",
                    ifNotExists ? "IF NOT EXISTS " : "",
                    schema,
                    newTable,
                    schema,
                    templateTable);
            sqlMapper.executeSql(sql);
            success = true;
            long endTime = System.currentTimeMillis();
            log.info("create table:{} success. 耗时:{}ms", newTable, endTime - startTime);

            // 写入缓存
            tableCache.computeIfAbsent(schema, k -> ConcurrentHashMap.newKeySet()).add(newTable);
        } catch (Exception e) {
            log.error("create table:{} fail.", newTable, e);
        }
        return success;
    }

    @Override
    public boolean tableExists(String schema, String tableName) {
        Set<String> tables = tableCache.get(schema);
        if (tables != null && tables.contains(tableName)) {
            return true;
        }

        boolean exists = sqlMapper.tableExists(schema, tableName) > 0;
        if (exists) {
            tableCache.computeIfAbsent(schema, k -> ConcurrentHashMap.newKeySet()).add(tableName);
        }
        return exists;
    }

    public void loadTableNames(String schema) {
        List<String> names = sqlMapper.listTableNames(schema);
        tableCache.put(schema, new HashSet<>(names));
        log.info("load {} tableNames success. size:{}", schema, names.size());
    }

    /**
     * 清空指定数据源的表名缓存
     *
     * @param schema 数据源名称
     */
    public void clearCache(String schema) {
        if (schema != null && !schema.isEmpty()) {
            Set<String> tables = tableCache.get(schema);
            if (tables != null) {
                tables.clear();
                log.info("Cleared table cache for data source: {}", schema);
            } else {
                log.warn("No cache found for data source: {}", schema);
            }
        } else {
            tableCache.clear();
            log.info("Cleared all table caches");
        }
    }

    /**
     * 清空所有数据源的表名缓存
     */
    @Override
    public void clearAllCache() {
        tableCache.clear();
        log.info("Cleared all table caches");
    }
}